package router

import (
	"admin-system-go/model"
	"admin-system-go/model/do"
	"admin-system-go/model/dto"
	"encoding/gob"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
)

var resources = make([]dto.ResourceBaseDTO, 0)

const apiVersion = "/api/v1.0"

// 传入的是一个密钥
// var store = cookie.NewStore([]byte("ddf4a512647842c28b1cfb9d3e052ffa"))
var store = cookie.NewStore([]byte(""))

func App() *gin.Engine {
	gob.Register(&do.Token{})
	r := gin.Default()
	r.Use(Cors())
	r.Use(sessions.Sessions("token", store))
	r.Use(Authorize())
	NewUserRouter().Register(r)
	NewRoleRouter().Register(r)
	NewUserGroupRouter().Register(r)
	NewResourceRouter().Register(r)
	NewMenuRouter().Register(r)
	NewResourceGroupRouter().Register(r)
	NewPermissionRouter().Register(r)
	FindAllResource(r)
	return r
}

func GetCurrentUid(context *gin.Context) uint {
	uid, _ := strconv.Atoi(sessions.Default(context).Get("uid").(string))
	return uint(uid)
}

// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		origin := c.Request.Header.Get("Origin")
		c.Header("Access-Control-Allow-Origin", origin)
		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
		c.Header("Access-Control-Allow-Credentials", "true")

		// 放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		// 处理请求
		c.Next()
	}
}

func FindAllResource(r *gin.Engine) {
	routers := r.Routes()
	for _, v := range routers {
		var path = v.Path
		var method = v.Method
		resources = append(resources, dto.ResourceBaseDTO{
			Path:   path,
			Method: method,
		})
	}
}

func Authorize() gin.HandlerFunc {
	return func(c *gin.Context) {
		url := c.Request.RequestURI
		if url == "/api/v1.0/user/login" {
			c.Next()
			return
		}
		session := sessions.Default(c)
		uid := session.Get("uid")
		token := session.Get(uid)
		if !checkToken(token) {
			c.Abort()
			c.JSON(http.StatusUnauthorized, model.UnauthorizedEntityModel)
			return
		}
		c.Next()
	}
}

func checkToken(token interface{}) bool {
	if token == nil {
		return false
	}

	if token.(*do.Token).Expired.Before(time.Now()) {
		return false
	}

	return true
}
